function GAME.CreateItem(item, pos, angles)

	local ent = ents.Create("prop_physics");
	
		ent:SetPos( pos );
		ent:SetAngles( angles );
		
		ent:SetVar( "ItemData", GAME.ItemData(item) );
		ent:SetModel( GAME.ItemData(item).Model );
		
	ent:Spawn();
		
	return ent;

end

--Used for existing items.
function GAME.SpawnItem(item, pos, angles)

	local ent = ents.Create("prop_physics");
	
		ent:SetPos( pos );
		ent:SetAngles( angles );
		
		ent:SetVar( "ItemData", item );
		ent:SetModel( item.Model );
		
	ent:Spawn();
		
	return ent;

end

function GAME.ItemData(item)

	for index, info in pairs( GAME.ItemList ) do
	
		if string.lower(info.Name) == string.lower(item) then
			
			GAME.ItemList[index].ID = tonumber( CurTime() + math.Rand(1, 10000) );
			
			return GAME.ItemList[index];
			
		end
		
	end

end

local PLAYER = FindMetaTable("Player");

--For use with Items within your inventory table.
function PLAYER:ItemCommand(item, cmd, slot) 

	local Function = GAME.ItemData( item ).FunctionList[cmd];

	if Function(self, slot) == "Default" then self:RemoveItem(slot);end
	
	return;

end

function PLAYER:DropItem(slot)

	local Item = self:CharacterGetData("Inventory")[slot];
	local tr = self:GetEyeTrace();
		
		GAME.SpawnItem( Item, self:GetPos(), self:GetAngles() );
		
	return;

end

--Remove the item from player inventory.
function PLAYER:RemoveItem(slot)

	local PlayerInv = self:CharacterGetData("Inventory") or {};
		
		table.remove( PlayerInv, slot );
		
	self:CharacterSetData( self:GetData("SelectedCharacter"), "Inventory", PlayerInv );
	
	return PlayerInv;

end

--Insert an either defined or non-defined item into the players inventory.
function PLAYER:InsertItem(item, ent)
	
	local PlayerInv = self:CharacterGetData("Inventory") or {};
	local Index = #PlayerInv + 1;
	local ItemInfo;
	
		PlayerInv[Index] = {};
		
	if IsValid(ent) then ItemInfo = ent:GetVar("ItemData");else ItemInfo = GAME.ItemData(item);end
		
	for index, info in pairs( ItemInfo ) do
		
		PlayerInv[Index][index] = info;
		
	end
	
	self:CharacterSetData( self:GetData("SelectedCharacter"), "Inventory", PlayerInv );
	
end

function GAME.ItemPickup(ply, key)

	if key == IN_USE then
	
		local tr = ply:GetEyeTrace();--Create a util func for a trace with a reasonable end pos rather than infinite.
		local ent = tr.Entity;
		
		if IsValid(ent) && ent:GetVar("ItemData") then
		
			ply:InsertItem( nil, ent );
			ent:Remove();

		end		
		
	end
	
end	
hook.Add("KeyPress", "ItemPlayerPickupCheck", GAME.ItemPickup);

--OH WHAT A HACKY METHOD FO' SHO'!
concommand.Add("ItemHandleUsage", function(ply, cmd, args)
	
	local arg = string.Explode(" ", args[1]);
	local CMD = tostring(arg[1]);
	local Slot = tonumber(arg[2]);
	local Item = ply:CharacterGetData("Inventory")[Slot].Name;
	
		ply:ItemCommand(Item, CMD, Slot);
	
	return args;

end);

/*////////////////////////////////////////
			*Debug Station*
*/////////////////////////////////////////

if GAME.Debug then

	function DebugSpawnTest(ply, cmd, args)
	
		local tr = util.QuickTrace(ply:GetShootPos(), ply:GetAimVector()*80, {ply});
		
		GAME.CreateItem( args[1], tr.HitPos, ply:GetAimVector() );
		
	end
	concommand.Add("gm_createitem", DebugSpawnTest);
	
	function DebugTestInfo(ply, cmd, args)
	
		local tr = ply:GetEyeTrace();
		
		if ValidEntity(tr.Entity) then
			
			PrintTable(tr.Entity:GetVar("ItemData"));
			
		end
	
	end
	concommand.Add("gm_infotest", DebugTestInfo);
	
end
